
/**
 * 前端文件上传，以七牛云为例子
 */
declare const uploadSDK:any; // 引入上传的sdk

const UPLOAD_TOKEN_NAME = 'uploadToken'; //本地存储的token名称
// 上传token缓存
const tokenCache = {
    val: '',
    expireDate:  new Date(),
}

// @to-do 获取上传token
const getUploadToken = ()=> Promise.resolve('获取上传的token');

// 获取5位随机数
const getRandomNumber = ()=>Math.floor(Math.random()*Math.pow(10,5));
// 统一配置文件路径，防止出现以/结尾和开头的路径
const handleFolder = (folder:string)=>{
    const delSuffix = String(folder).endsWith('/')?String(folder).slice(0,-1):String(folder);
    const delPrefix = String(delSuffix).startsWith('/')?String(delSuffix).slice(1):String(delSuffix);
    return delPrefix;
};


export const cachedUploadToken = ()=> getUploadToken().then((res:any)=>{
    tokenCache.val = res?.token;
    // @to-do：设置token的过期时间
    tokenCache.expireDate = new Date(res?.expireTime);
    // @to-do: 上传token本地存储，其他平台可能要其他的, 注意这里值和过期时间都要存储的
    localStorage.setItem( UPLOAD_TOKEN_NAME,JSON.stringify(tokenCache));
})

// 单文件上传
export const uploadSingleFile = async ({ file, folder='', }: { file: File, folder:string, })=> {
    if(!tokenCache.val){
        const localToken = JSON.parse(localStorage.getItem(UPLOAD_TOKEN_NAME)||'{}');
        tokenCache.val = localToken?.val;
        tokenCache.expireDate = new Date(localToken?.expireDate);
    }

    if(!tokenCache.expireDate.getTime()||new Date()>tokenCache.expireDate){
        await cachedUploadToken();
    }

    // @to-do：正式上传文件，以七牛云为例子，切换其他可能要修改
    const observable = uploadSDK.upload(
        file, 
        `${handleFolder(folder)}/${getRandomNumber()}-${(file?.name)}`, 
        tokenCache.val, 
        {}, 
        {}
    );
    let resolveFn:(path:string)=>void, rejectFn: (err:Error)=>void;
    const promise = new Promise<string>((resolve,reject)=>{
        resolveFn = resolve;
        rejectFn = reject;
    });
    const subscription = observable.subscribe({
        next(){

        },
        error(err:Error){
            // @to-do: 打印错误日志，并提示用户
            rejectFn(err)
        },
        complete(res:any){
            // @to-do: 拼接文件的url 
            const urlPath = '拼接文件的URL';
            resolveFn(urlPath);
        }
    }); // 上传开始

    return promise;
}

export const FileSizeEnum = {
    GB: 'GB',
    MB: 'MB',
    KB: 'KB',
    B: 'B',
}

// 1GB、1MB、1KB或1B对应的字节数Bytes数
const FileUnitSizeOfBytesMap = {
    [ FileSizeEnum.B ]: 1,
    [ FileSizeEnum.KB ]: Math.pow(2,10),
    [ FileSizeEnum.MB ]: Math.pow(2,20),
    [ FileSizeEnum.GB ]: Math.pow(2,30),
}

/***** 文件的其他操作 *****/

// 获取文件大小
export const formatFileSize = (file:File, unit=FileSizeEnum.MB)=>{
    if(!(file instanceof File)){
        return 0;
    }
    if(!FileUnitSizeOfBytesMap[unit]){
        console.warn(`文件大小类型单位不支持`);
        return 0;
    }
    return file.size/FileUnitSizeOfBytesMap[unit];
}

// 检查Mimal文件类型 是否合格, 如 image/png匹配 image/*
export const checkFileMimalType = (fileType:string, targetTypeStr:string)=>{
    const checkMime = (targetType:string)=>{
        if(fileType&&targetType){
            const mainFileType = String(fileType).split('/')[0], subFileType = String(fileType).split('/')[1];
            const tagetMainType = String(targetType).split('/')[0], targetSubType = String(targetType).split('/')[1];
            if(tagetMainType=='*'){
                // 全匹配
                return true;
            }
    
            if(tagetMainType==mainFileType&&( targetSubType=='*'||targetSubType==subFileType )){
                return true;
            }
        }
    
        return false;
    }
    return String(targetTypeStr).split(',').some(checkMime);
}